Imports System.Text.RegularExpressions
Imports System.IO
Imports Microsoft.Win32

Public Class MainForm

    Enum ListTypeEnum
        Avail
        Blocked
        Integrated
    End Enum

    ''' <summary>
    ''' Stores the last run listing type, which is run whenever an operation is complete. 
    ''' Also used for initial type.
    ''' </summary>
    ''' <remarks></remarks>
    Protected LastListType As ListTypeEnum = ListTypeEnum.Avail

    Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim tortoisePath As String = Nothing
        Do
            If Not IsNothing(FindTortoiseProc(tortoisePath)) Then
                Exit Do
            End If
        Loop While MessageBox.Show("Cannot find TortoiseSVN (expected " & tortoisePath & ")", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning) = Windows.Forms.DialogResult.Retry

        ' load from registry
        LoadEntries()

        ShowList(LastListType)
    End Sub

    Private Sub MainForm_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        ' save to registry
        SaveEntries()
    End Sub


    Private _directory As String
    Protected Property CurrentDirectory() As String
        Get
            Return _directory
        End Get
        Set(ByVal value As String)
            If _directory <> value Then
                _directory = value

                ' run validation only if its changed
                If ValidateForm() Then
                    ShowList(LastListType)
                End If
            End If

            ' make sure gui is synchronized to this
            If uiDirectory.Text <> value Then
                uiDirectory.Text = value
            End If
        End Set
    End Property


#Region "svnmerge list parsing/handling"
    ''' <summary>
    ''' Shows a list of revisions, using the specified operation (avail, blocked, etc)
    ''' </summary>
    ''' <param name="type"></param>
    ''' <remarks></remarks>
    Private Sub ShowList(ByVal type As ListTypeEnum)
        If Not ValidateForm() Then
            Return
        End If

        LastListType = type

        Dim args As String
        Select Case type
            Case ListTypeEnum.Blocked
                args = "avail -B -l"
            Case ListTypeEnum.Integrated
                args = "integrated -l"
            Case Else ' ListTypeEnum.Avail
                args = "avail -l"
        End Select

        uiStatus.Text = "Running svnmerge.exe.."
        uiInit.Enabled = False
        uiListButtons.Enabled = False
        uiActionButtons.Enabled = False
        uiList.Enabled = False
        uiList.DataSource = Nothing

        Application.DoEvents()

        
        Dim output As String = Nothing, errors As String = Nothing
        If RunSvnMerge(args, output, errors) <> 0 Then
            If errors.Contains("no integration info available") Then
                uiStatus.Text = "svnmerge has not been initialized on this branch"
                uiInit.Enabled = True

                uiListButtons.Enabled = False
                uiActionButtons.Enabled = False
                uiList.Visible = False
                Return
            End If

            uiStatus.Text = "Execution of svnmerge.exe failed"
            MessageBox.Show(errors, "Command failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return
        End If

        uiInit.Enabled = False
        uiListButtons.Enabled = True
        uiActionButtons.Enabled = True

        Dim lineSplit As New Regex("----+")

        If lineSplit.Match(output).Success Then

            Dim revDetailsRegex As New Regex("r(\d+)\s*\|\s*(\w+)\s*\|\s*([a-z0-9-: \(\),]+)\s*\|", RegexOptions.Multiline Or RegexOptions.IgnoreCase)
            ' g1 = rev, g2= user, g3 = date
            Dim pathsRegex As New Regex("^\s{4}([A-Z])\s(.*)$", RegexOptions.Multiline)
            Dim descRegex As New Regex("\n\n(.*)", RegexOptions.Multiline Or RegexOptions.Singleline)

            Dim table As New Data.DataTable
            table.Columns.Add("Revision")
            table.Columns.Add("User")
            table.Columns.Add("Date")
            table.Columns.Add("Description")
            With table.Columns.Add("Paths")
                .ColumnMapping = MappingType.Hidden
            End With
            With table.Columns.Add("Output")
                .ColumnMapping = MappingType.Hidden
            End With

            Dim revInfoChunks As String() = lineSplit.Split(output)
            For Each revinfo As String In revInfoChunks
                Dim revDetails As Match = revDetailsRegex.Match(revinfo)
                Dim revDesc As Match = descRegex.Match(revinfo.Replace(vbCr, ""))
                Dim revPaths As Match = pathsRegex.Match(revinfo)

                If revDetails.Success Then
                    Dim row As Data.DataRow = table.NewRow
                    row("Revision") = revDetails.Groups(1).Value.Trim
                    row("User") = revDetails.Groups(2).Value.Trim
                    row("Date") = revDetails.Groups(3).Value.Trim

                    If revDesc.Success Then
                        row("Description") = revDesc.Groups(1).Value.Trim
                    End If

                    If revPaths.Success Then
                        row("Paths") = revPaths.Value
                    End If

                    row("Output") = revinfo

                    table.Rows.Add(row)
                End If
            Next

            table.DefaultView.AllowNew = False
            table.DefaultView.AllowDelete = False
            table.DefaultView.AllowEdit = False

            uiList.DataSource = table
            uiList.Enabled = True
            uiList.Visible = True
            
            uiList.Columns("Revision").Width = 55
            uiList.Columns("User").Width = 65
            uiList.Columns("Date").FillWeight = 25
            uiList.Columns("Date").AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
            uiList.Columns("Description").AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill


            Select Case type
                Case ListTypeEnum.Avail
                    uiStatus.Text = "Showing revisions available to merge"
                Case ListTypeEnum.Blocked
                    uiStatus.Text = "Showing blocked revisions"
                Case ListTypeEnum.Integrated
                    uiStatus.Text = "Showing integrated revisions"
                Case Else
                    uiStatus.Text = ""
            End Select
        Else
            uiStatus.Text = "Nothing to show"
        End If


        uiMerge.Enabled = (type = ListTypeEnum.Avail)
        uiBlock.Enabled = (type = ListTypeEnum.Avail)
        uiUnblock.Enabled = (type = ListTypeEnum.Blocked)
        uiRollback.Enabled = (type = ListTypeEnum.Integrated)
    End Sub

    Private Sub uiList_MouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles uiList.MouseDoubleClick
        ' get the original data row 
        Dim row As DataRow
        Try
            Dim gridrow As DataGridViewRow = uiList.SelectedRows(0)
            row = DirectCast(gridrow.DataBoundItem, DataRowView).Row
        Catch ex As Exception
            Return
        End Try

        ' show a dialog box with revision information 
        MessageBox.Show(row("Output").ToString.Replace(vbCr, ""), "Details for revision " & row("Revision"))
    End Sub

    ''' <summary>
    ''' Gets a list of all the selected revisions, in comma-delimited format 
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetSelectedRevList() As String
        Dim revs As New Generic.List(Of String)
        For Each row As DataGridViewRow In uiList.Rows
            Try
                If CBool(row.Cells(0).Value) Then
                    revs.Add(CInt(row.Cells("Revision").Value))
                End If
            Catch ex As Exception
                Continue For
            End Try
        Next

        Return String.Join(",", revs.ToArray)
    End Function


#End Region

#Region "Executable helpers (svnmerge.exe / tortoise)"
    ''' <summary>
    ''' Runs the svnmerge.exe executable
    ''' </summary>
    ''' <param name="arguments"></param>
    ''' <param name="stdout"></param>
    ''' <param name="stderr"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Function RunSvnMerge(ByVal arguments As String, ByRef stdout As String, ByRef stderr As String) As Integer
        Dim path As String = Application.ExecutablePath
        path = path.Substring(0, path.LastIndexOf("\"))

        System.IO.Directory.SetCurrentDirectory(CurrentDirectory)

        Return RunApplication(path & "\svnmerge.exe", arguments, stdout, stderr)
    End Function

    ''' <summary>
    ''' Runs an application, capturing stdout and stderr
    ''' </summary>
    ''' <param name="exename"></param>
    ''' <param name="arguments"></param>
    ''' <param name="stdout"></param>
    ''' <param name="stderr"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Function RunApplication(ByVal exename As String, ByVal arguments As String, ByRef stdout As String, ByRef stderr As String) As Integer
        ' Set start information.
        Dim start_info As New ProcessStartInfo(exename)
        start_info.UseShellExecute = False
        start_info.CreateNoWindow = True
        start_info.RedirectStandardOutput = True
        start_info.RedirectStandardError = True
        start_info.RedirectStandardInput = True
        start_info.Arguments = arguments
        For Each key As String In System.Environment.GetEnvironmentVariables().Keys
            start_info.EnvironmentVariables(key) = System.Environment.GetEnvironmentVariable(key)
        Next
        start_info.EnvironmentVariables("PATH") = System.Environment.GetEnvironmentVariable("PATH")

        ' Make the process and set its start information.
        Dim proc As New Process()
        proc.StartInfo = start_info

        ' Start the process.
        proc.Start()

        ' Attach to stdout and stderr.
        Dim std_out As StreamReader = proc.StandardOutput()
        Dim std_err As StreamReader = proc.StandardError()
        Dim std_in As StreamWriter = proc.StandardInput()

        ' Display the results.
        stdout = std_out.ReadToEnd()
        stderr = std_err.ReadToEnd()
        Dim exitCode As Integer = proc.ExitCode

        ' Clean up.
        std_out.Close()
        std_err.Close()
        proc.Close()

        Return exitCode
    End Function

    ''' <summary>
    ''' Shows the tortoiseSVN commit dialog
    ''' </summary>
    ''' <param name="commitFile"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Function ShowTortoiseCommit(ByVal commitFile As String) As Boolean
        Dim args As String = "/command:commit /logmsgfile:""" & commitFile & """ /path:""" & CurrentDirectory & """ /notempfile"

        Dim path As String = FindTortoiseProc()
        If IsNothing(path) Then
            Return False
        End If

        Shell(path & " " & args, AppWinStyle.NormalFocus, True, 300000)
        Return True
    End Function

    ''' <summary>
    ''' Shows the tortoisesvn revert dialog
    ''' </summary>
    ''' <param name="commitFile"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Function ShowTortoiseRevert(ByVal commitFile As String) As Boolean
        Dim args As String = "/command:revert /path:""" & CurrentDirectory & """ /notempfile"

        Dim path As String = FindTortoiseProc()
        If IsNothing(path) Then
            Return False
        End If

        Shell(path & " " & args, AppWinStyle.NormalFocus, True, 300000)
        Return True
    End Function

    ''' <summary>
    ''' Shows the tortoisesvn update dialog
    ''' </summary>
    ''' <param name="commitFile"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Function ShowTortoiseUpdate(ByVal commitFile As String) As Boolean
        Dim args As String = "/command:update /path:""" & CurrentDirectory & """ /notempfile"

        Dim path As String = FindTortoiseProc()
        If IsNothing(path) Then
            Return False
        End If

        Shell(path & " " & args, AppWinStyle.NormalFocus, True, 300000)
        Return True
    End Function

    ''' <summary>
    ''' Finds the path to the TortoiseProc.exe file 
    ''' </summary>
    ''' <param name="path">The path to the executable found.</param>
    ''' <returns>Nothing if path not found</returns>
    ''' <remarks></remarks>
    Protected Function FindTortoiseProc(Optional ByRef path As String = "") As String
        ' get programfiles path 
        Dim programFiles As String = System.Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)
        If IsNothing(programFiles) OrElse programFiles.Trim = "" Then
            ' read from environment
            programFiles = Environment.GetEnvironmentVariable("ProgramFiles")

            If IsNothing(programFiles) OrElse programFiles.Trim = "" Then
                ' set manually
                programFiles = "C:\Program Files\"
            End If
        End If
        ' make sure it has trailing \ 
        If Not programFiles.EndsWith("\") Then programFiles &= "\"

        ' assume path to tortoiseproc 
        path = programFiles & "TortoiseSVN\bin\TortoiseProc.exe"
        If IO.File.Exists(path) Then
            Return path
        End If

        Return Nothing
    End Function

#End Region

#Region "List button events"
    Private Sub uiAvail_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uiAvail.Click
        ShowList(ListTypeEnum.Avail)
    End Sub

    Private Sub uiBlocked_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uiBlocked.Click
        ShowList(ListTypeEnum.Blocked)
    End Sub

    Private Sub uiMerged_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uiMerged.Click
        ShowList(ListTypeEnum.Integrated)
    End Sub
#End Region

#Region "Action buttons"
    Private Sub uiMerge_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uiMerge.Click
        Dim revs As String = GetSelectedRevList()
        If revs.Length = 0 Then
            MessageBox.Show("No revisions selected", "Invalid", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Return
        End If

        If MessageBox.Show("Are you sure you want to merge revisions: " & vbNewLine & revs, _
                           "Confirm merge", MessageBoxButtons.YesNo, MessageBoxIcon.Question) _
           = Windows.Forms.DialogResult.Yes Then

            Dim commitFile As String = System.IO.Path.GetTempFileName()

            Dim output As String = Nothing, errors As String = Nothing
            If RunSvnMerge("merge -r " & revs & " -f """ & commitFile & """", output, errors) <> 0 Then
                uiStatus.Text = "Error running svnmerge.exe"
                MessageBox.Show(errors, "Command failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return
            End If

            ShowTortoiseCommit(commitFile)

            uiStatus.Text = "Merged revisions " & revs
            ShowList(LastListType)
        End If
    End Sub

    Private Sub uiBlock_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles uiBlock.Click
        Dim revs As String = GetSelectedRevList()
        If revs.Length = 0 Then
            MessageBox.Show("No revisions selected", "Invalid", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Return
        End If

        If MessageBox.Show("Are you sure you want to block revisions: " & vbNewLine & revs, _
                           "Confirm block", MessageBoxButtons.YesNo, MessageBoxIcon.Question) _
           = Windows.Forms.DialogResult.Yes Then

            Dim commitFile As String = System.IO.Path.GetTempFileName()

            Dim output As String = Nothing, errors As String = Nothing
            If RunSvnMerge("block -r " & revs & " -f """ & commitFile & """", output, errors) <> 0 Then
                uiStatus.Text = "Error running svnmerge.exe"
                MessageBox.Show(errors, "Command failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return
            End If

            ShowTortoiseCommit(commitFile)

            uiStatus.Text = "Blocked revisions " & revs
            ShowList(LastListType)
        End If
    End Sub

    Private Sub uiUnblock_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles uiUnblock.Click
        Dim revs As String = GetSelectedRevList()
        If revs.Length = 0 Then
            MessageBox.Show("No revisions selected", "Invalid", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Return
        End If

        If MessageBox.Show("Are you sure you want to unblock revisions: " & vbNewLine & revs, _
                           "Confirm unblock", MessageBoxButtons.YesNo, MessageBoxIcon.Question) _
           = Windows.Forms.DialogResult.Yes Then

            Dim commitFile As String = System.IO.Path.GetTempFileName()

            Dim output As String = Nothing, errors As String = Nothing
            If RunSvnMerge("unblock -r " & revs & " -f """ & commitFile & """", output, errors) <> 0 Then
                uiStatus.Text = "Error running svnmerge.exe"
                MessageBox.Show(errors, "Command failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return
            End If

            ShowTortoiseCommit(commitFile)

            uiStatus.Text = "Unblocked revisions " & revs
            ShowList(LastListType)
        End If
    End Sub

    Private Sub uiRollback_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles uiRollback.Click
        Dim revs As String = GetSelectedRevList()
        If revs.Length = 0 Then
            MessageBox.Show("No revisions selected", "Invalid", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Return
        End If

        If MessageBox.Show("Are you sure you want to rollback previously merged revisions: " & vbNewLine & revs, _
                           "Confirm rollback", MessageBoxButtons.YesNo, MessageBoxIcon.Question) _
           = Windows.Forms.DialogResult.Yes Then

            Dim commitFile As String = System.IO.Path.GetTempFileName()

            Dim output As String = Nothing, errors As String = Nothing
            If RunSvnMerge("merge -r " & revs & " -f """ & commitFile & """", output, errors) <> 0 Then
                uiStatus.Text = "Error running svnmerge.exe"
                MessageBox.Show(errors, "Command failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return
            End If

            ShowTortoiseCommit(commitFile)

            uiStatus.Text = "Rolled back revisions " & revs
            ShowList(LastListType)
        End If
    End Sub
#End Region

#Region "revert/commit/init buttons"
    ' these are just to help, if you hit cancel on the tortoise dialog or whatever

    Private Sub uiRevert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uiRevert.Click
        ShowTortoiseRevert("")
        ShowList(LastListType)
    End Sub

    Private Sub uiCommit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uiCommit.Click
        ShowTortoiseCommit("")
        ShowList(LastListType)
    End Sub

    Private Sub uiUpdate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles uiUpdate.Click
        ShowTortoiseUpdate("")
        ShowList(LastListType)
    End Sub

    Private Sub uiInit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uiInit.Click
        If MessageBox.Show("Are you sure you want to initialize merge tracking on this working copy? Make sure this is the root of the branch!", _
                                   "Confirm initialize", MessageBoxButtons.YesNo, MessageBoxIcon.Question) _
                   = Windows.Forms.DialogResult.Yes Then

            Dim commitFile As String = System.IO.Path.GetTempFileName()

            Dim output As String = Nothing, errors As String = Nothing
            If RunSvnMerge("init -f """ & commitFile & """", output, errors) <> 0 Then
                uiStatus.Text = "Error running svnmerge.exe"
                MessageBox.Show(errors, "Command failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return
            End If

            ShowTortoiseCommit(commitFile)

            uiStatus.Text = "Merge tracking initialized"
            ShowList(ListTypeEnum.Avail) ' no point in doing anything else besides avail
        End If
    End Sub
#End Region

#Region "Directory UI stuff"
    Private Sub uiDirectory_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uiDirectory.Enter
        uiDirectory.SelectAll()
    End Sub

    Private Sub uiDirectorySelect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uiDirectorySelect.Click
        If IO.Directory.Exists(uiDirectory.Text) Then
            uiDirectoryDialog.SelectedPath = uiDirectory.Text
        End If
        If uiDirectoryDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
            uiDirectory.Text = uiDirectoryDialog.SelectedPath
        End If
        CurrentDirectory = uiDirectory.Text.Trim
    End Sub

    Private Sub uiDirectory_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles uiDirectory.KeyPress
        If e.KeyChar = vbCr Or e.KeyChar = vbLf Or e.KeyChar = vbTab Then
            CurrentDirectory = uiDirectory.Text
        End If
    End Sub

    Private Sub uiDirectory_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles uiDirectory.SelectedIndexChanged
        CurrentDirectory = uiDirectory.Text
    End Sub

    Private Sub uiDirectory_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uiDirectory.Leave
        CurrentDirectory = uiDirectory.Text
    End Sub

    ''' <summary>
    ''' Validates that a valid directory has been entered 
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Function ValidateForm() As Boolean
        Static valid As Boolean = True

        Dim dir As String = CurrentDirectory

        If dir = "" Then
            ' empty - no message
            valid = False
            SetControls(False)
            Return False
        End If

        If Not IO.Directory.Exists(dir) Then
            If valid Then
                ' only show message box once 
                MessageBox.Show("Directory does not exist", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
            valid = False
            SetControls(False)
            Return False
        End If

        If Not dir.EndsWith("\") Then dir &= "\"

        If Not IO.Directory.Exists(dir & ".svn") Then
            If valid Then
                MessageBox.Show("Directory does not appear to be a working copy", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
            valid = False
            SetControls(False)
            Return False
        End If

        'TODO: check for root of WC
        ' bonus points: automatically switch to it, if not there 
        ' dir-prop-base does not indicate root.. crap.
        'While Not IO.File.Exists(dir & ".svn\dir-prop-base")
        '    dir &= "..\"
        '    If Not IO.Directory.Exists(dir & ".svn") Then
        '        If Not valid Then
        '            MessageBox.Show("Cannot find root of working copy! Looking for .svn\dir-prop-base", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        '        End If
        '        valid = False
        '        SetControls(False)
        '        Return False
        '    End If
        'End While

        dir = IO.Path.GetFullPath(dir)
        
        ' add to history
        If uiDirectory.Items.IndexOf(dir) > 0 Then
            ' remove it, so it moves to top of list
            uiDirectory.Items.Remove(dir)
        End If
        If Not uiDirectory.Items.Contains(dir) Then
            uiDirectory.Items.Insert(0, dir)
        End If
        uiDirectory.SelectedIndex = 0


        SetControls(True)
        valid = True
        Return True
    End Function

    Private Sub RemoveListDuplicates()
        
    End Sub

    Private Sub SetControls(ByVal enabled As Boolean)
        uiActionButtons.Enabled = enabled
        uiListButtons.Enabled = enabled
        'uiList.Enabled = enabled
        uiList.Visible = enabled
        uiInit.Enabled = enabled
    End Sub
#End Region

    Protected Sub SaveEntries()
        My.Settings.Entries = New Specialized.StringCollection()
        For Each item As Object In uiDirectory.Items
            My.Settings.Entries.Add(item.ToString)
        Next

        My.Settings.FormHeight = Me.Height
        My.Settings.FormWidth = Me.Width
        My.Settings.FormX = Me.Left
        My.Settings.FormY = Me.Top


        'Dim regkey As RegistryKey = Nothing
        'Try
        '    regkey = Registry.CurrentUser.OpenSubKey("Software\SvnMergeGui\Entries", True)
        '    If IsNothing(regkey) Then
        '        regkey = Registry.CurrentUser.CreateSubKey("Software\SvnMergeGui\Entries", RegistryKeyPermissionCheck.Default)
        '    End If

        '    ' remove old entries
        '    For Each key As String In regkey.GetValueNames()
        '        regkey.DeleteValue(key)
        '    Next

        '    ' write values
        '    For i As Integer = 0 To uiDirectory.Items.Count - 1
        '        regkey.SetValue(i, uiDirectory.Items(i).ToString)
        '    Next
        'Catch
        '    ' ignore
        'Finally
        '    If Not IsNothing(regkey) Then
        '        regkey.Close()
        '    End If
        'End Try
    End Sub

    Protected Sub LoadEntries()
        If My.Settings.FormHeight >= 0 Then Me.Height = My.Settings.FormHeight
        If My.Settings.FormWidth >= 0 Then Me.Width = My.Settings.FormWidth
        If My.Settings.FormX >= 0 Then Me.Left = My.Settings.FormX
        If My.Settings.FormY >= 0 Then Me.Top = My.Settings.FormY

        If Not IsNothing(My.Settings.Entries) AndAlso TypeOf My.Settings.Entries Is Specialized.StringCollection Then
            uiDirectory.Items.Clear()
            For Each item As String In My.Settings.Entries
                uiDirectory.Items.Add(item)
            Next
        End If

        'Dim regkey As RegistryKey = Nothing
        'Try
        '    regkey = Registry.CurrentUser.OpenSubKey("Software\SvnMergeGui\Entries")

        '    If IsNothing(regkey) Then
        '        Return
        '    End If

        '    uiDirectory.Items.Clear()

        '    For Each key As String In regkey.GetValueNames()
        '        Dim dir As String = regkey.GetValue(key)
        '        If IO.Directory.Exists(dir) AndAlso Not uiDirectory.Items.Contains(dir) Then
        '            uiDirectory.Items.Add(dir)
        '        End If
        '    Next

        '    If uiDirectory.Items.Count > 0 Then
        '        uiDirectory.SelectedIndex = 0
        '    End If

        '    regkey.Close()
        'Catch
        '    ' ignore
        'Finally
        '    If Not IsNothing(regkey) Then
        '        regkey.Close()
        '    End If
        'End Try
    End Sub

End Class
